package sandbox.psyomn;

import helpers.Configuration;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * Class that handles generic requests to the database.
 * This is a singleton because it needs atomic access
 * to the sqlite database (it's actually possible to 
 * have multiple threads access the database, but it 
 * is advised against on sqlite.org:
 * 	
 * 		http://www.sqlite.org/faq.html#q6
 * ). 
 * 
 * As a result this class is implemented as a singleton
 * 
 * @author psyomn
 */

public class Executor
{
	/**
	 * The instance of the class
	 */
	private static Executor mInst = null;
	
	/**
	 * The db handle for the class
	 */
	private Connection mConn = null;
	
	/**
	 * The constructor for the singleton here. The connection
	 * is created here.
	 * @throws Exception
	 */
	private Executor()
	{
		try
		{
			Class.forName("org.sqlite.JDBC");
			mConn  = DriverManager.getConnection("jdbc:sqlite:" + Configuration.getAttribute("dbname"));
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * The instance getter for this class. 
	 * @return the instance of the class 
	 * @throws Exception
	 */
	public synchronized static Executor getInst()
	{
		if (null==mInst)
		{
			mInst = new Executor(); 
		}
		
		return mInst; 
	}
	
	/**
	 * Executes sql on selected database from configuration file.
	 * This is synchronized to ensure atomic access.
	 * @param sql the sql statement to be processed
	 */
	public synchronized ResultSet execute(String sql)
	{
		ResultSet rs = null; 
		Statement statement;
		
		try
		{
			statement = mConn.createStatement();	
			rs = statement.executeQuery(sql);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return rs; 
	}
	
	/**
	 * For prepared statements. 
	 * Since read only, not synchronized.  
	 */
	public Connection getConnection()
	{
		return mConn; 
	}
}
